

package top.continew.admin.rpc;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.shengchao.examstar.rpc.knowledge.api.IKnowledgeRpc;
import cn.shengchao.examstar.rpc.knowledge.req.KnowledgeReq;
import cn.shengchao.examstar.rpc.knowledge.resp.KnowledgePointDto;
import com.shengchao.examstar.rpc.question.api.IQuestionIndexRpc;
import com.shengchao.examstar.rpc.question.base.PageResult;
import com.shengchao.examstar.rpc.question.enums.QuestionSetTypeEnum;
import com.shengchao.examstar.rpc.question.enums.UserQuestionSetStatusEnum;
import com.shengchao.examstar.rpc.question.req.IndexKnowledgeReq;
import com.shengchao.examstar.rpc.question.resp.IndexKnowledge;
import com.shengchao.examstar.rpc.question.resp.IndexQuestionStatistics;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.question.user.service.IUserQuestionService;
import top.continew.admin.question.user.service.impl.QuestionService;
import top.continew.admin.question.user.service.question.enums.ProblemStateEnum;

import java.text.NumberFormat;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@DubboService
public class QuestionIndexRpc implements IQuestionIndexRpc {

    @Autowired
    private IUserQuestionService userQuestionService;

    @DubboReference
    private IKnowledgeRpc iKnowledgeRpc;
    @Autowired
    private QuestionService questionService;

    @Override
    public IndexQuestionStatistics getQuestionStatistics(Long specificationType) throws Exception {
        Long userId = UserContextHolder.getUserId();
        IndexQuestionStatistics indexQuestionStatistics = new IndexQuestionStatistics();
        // 获取用户做题总数
        Long questionSum = userQuestionService.getDoQuestionSumBySpecificationType(userId, specificationType);
        indexQuestionStatistics.setQuestionSum(questionSum);
        // 昨天天数
        Long doQuestionDay = userQuestionService.getDoQuestionDay(userId, specificationType);
        indexQuestionStatistics.setDoQuestionDay(doQuestionDay);
        // 上次做题
        Long lastTimeDoSum = userQuestionService.getQuestionLastTimeDoSum(userId, specificationType);
        // 今日做题
        Long todayDoSum = userQuestionService.getQuestionTodayDoSum(userId, specificationType);
        indexQuestionStatistics.setDoQuestionDayCompare(todayDoSum - lastTimeDoSum);
        return indexQuestionStatistics;
    }

    @Override
    public PageResult<IndexKnowledge> getKnowledge(IndexKnowledgeReq indexKnowledgeReq) {
        KnowledgeReq knowledgeReq = new KnowledgeReq();
        knowledgeReq.setPath(indexKnowledgeReq.getPath());
        knowledgeReq.setSpecificationType(indexKnowledgeReq.getSpecificationType());
        if (StrUtil.isNotBlank(indexKnowledgeReq.getKnowledgeTags())) {
            knowledgeReq.setTags(Arrays.stream(indexKnowledgeReq.getKnowledgeTags().split("-"))
                .map(Long::parseLong)
                .toList());
        }
        knowledgeReq.setName(indexKnowledgeReq.getSearchValue());
        knowledgeReq.setSize(indexKnowledgeReq.getSize());
        knowledgeReq.setPage(indexKnowledgeReq.getPage());
        //获取知识点
        cn.shengchao.examstar.rpc.base.PageResult<KnowledgePointDto> knowledgePointDtoPageResult = iKnowledgeRpc
            .getKnowledgePointList(knowledgeReq);
        List<KnowledgePointDto> knowledgePointDtos = knowledgePointDtoPageResult.getList();
        List<IndexKnowledge> indexKnowledgeList = getIndexKnowledge(knowledgePointDtos);
        return PageResult.of((long)knowledgePointDtoPageResult.getTotal(), indexKnowledgeList);
    }

    @Override
    public List<IndexKnowledge> getKnowledgeByPointDtos(JSONArray jsonArray) throws Exception {
        if (jsonArray.isEmpty()) {
            return List.of();
        } else {
            List<KnowledgePointDto> knowledgePointDtos = jsonArray.toList(KnowledgePointDto.class);
            List<IndexKnowledge> indexKnowledgeList = getIndexKnowledge(knowledgePointDtos);
            return indexKnowledgeList;
        }

    }

    @Override
    public List<IndexKnowledge> getIndexKnowledgeById(List<Long> knowledgePointIds) {
        return getIndexKnowledge(knowledgePointIds.stream().map(item -> {
            KnowledgePointDto knowledgePointDto = new KnowledgePointDto();
            knowledgePointDto.setId(item);
            return knowledgePointDto;
        }).toList());
    }

    @NotNull
    private List<IndexKnowledge> getIndexKnowledge(List<KnowledgePointDto> knowledgePointDtos) {
        List<IndexKnowledge> indexKnowledgeList = knowledgePointDtos.stream().map(knowledgePointDto -> {
            IndexKnowledge indexKnowledge = new IndexKnowledge();
            indexKnowledge.setKnowledgeTags(knowledgePointDto.getTags());
            indexKnowledge.setKnowledgeName(knowledgePointDto.getName());
            indexKnowledge.setQuestionSetId(knowledgePointDto.getId());
            return indexKnowledge;
        }).toList();
        Long userId = UserContextHolder.getUserId();
        // 使用CompletableFuture异步处理标签信息
        ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
        List<CompletableFuture<Void>> futures = indexKnowledgeList.stream()
            .map(dto -> CompletableFuture.runAsync(() -> {
                //获取知识点题目数量
                long questionSum = questionService.getQuestionSum(dto
                    .getQuestionSetId(), QuestionSetTypeEnum.KNOWLEDGE_POINT_EXERCISE.getCode());
                dto.setQuestionSum(questionSum);
                dto.setTrueInterestRate(0.0);
                dto.setDoQuestionSum(0L);
                dto.setIndex(1L);
                if (questionSum != 0) {
                    long questionSetId = questionService.getQuestionSetId(dto.getQuestionSetId());
                    //获取知识点做题数
                    long doSum = userQuestionService.getDoQuestionSum(userId, questionSetId);
                    dto.setDoQuestionSum(doSum);
                    if (doSum != 0) {
                        //正确数量
                        long doTrueSum = userQuestionService
                            .getDoQuestionSum(userId, questionSetId, ProblemStateEnum.RIGHT);
                        NumberFormat nf = NumberFormat.getNumberInstance();
                        nf.setMaximumFractionDigits(2);
                        dto.setTrueInterestRate(Double.valueOf(nf.format(doTrueSum * 100.0 / doSum)));
                    }
                    Long index = userQuestionService.getUserIndex(userId, questionSetId);
                    dto.setIndex(index);
                }
                dto.setStatus(UserQuestionSetStatusEnum.of(questionSum, dto.getDoQuestionSum()).getCode());
            }, executorService))
            .toList();
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        return indexKnowledgeList;
    }
}
